#include <iostream>
#include <thread>
#include <random>
#include <chrono>
#include <atomic>

std::mt19937 rng(std::random_device{}());
std::uniform_int_distribution<> dis(0, 100);

const int windowSize = 5;
std::atomic<int> sendBase(0);
std::atomic<int> nextSeqNum(0);
std::atomic<bool> receivedAck[windowSize];
std::atomic<bool> stop(false);

void sender() {
    while (!stop) {
        while (nextSeqNum - sendBase < windowSize) {
            std::cout << "Sender: Sending packet " << nextSeqNum << std::endl;
            // 模拟丢包，10%概率丢包
            if (dis(rng) > 10) {
                receivedAck[nextSeqNum % windowSize] = true;
            } else {
                receivedAck[nextSeqNum % windowSize] = false;
            }
            nextSeqNum++;
            std::this_thread::sleep_for(std::chrono::seconds(1));
        }

        for (int i = 0; i < windowSize; i++) {
            if (receivedAck[(sendBase + i) % windowSize]) {
                std::cout << "Sender: Received ACK for packet " << sendBase + i << std::endl;
                receivedAck[(sendBase + i) % windowSize] = false;
                sendBase++;
            }
        }
    }
}

void receiver() {
    while (!stop) {
        for (int i = 0; i < windowSize; i++) {
            if (receivedAck[i]) {
                std::cout << "Receiver: Received packet " << (sendBase + i) % windowSize << ", sending ACK" << std::endl;
                receivedAck[i] = false;
            }
        }
        std::this_thread::sleep_for(std::chrono::seconds(1));
    }
}

void monitor() {
    while (!stop) {
        std::cout << "Window status:" << std::endl;
        std::cout << "已发送并收到确认: ";
        for (int i = 0; i < sendBase; i++) {
            std::cout << i << " ";
        }
        std::cout << std::endl;

        std::cout << "已发送但未收到确认: ";
        for (int i = sendBase; i < nextSeqNum; i++) {
            std::cout << i << " ";
        }
        std::cout << std::endl;

        std::cout << "允许发送但尚未发送: ";
        for (int i = nextSeqNum; i < sendBase + windowSize; i++) {
            std::cout << i << " ";
        }
        std::cout << std::endl;

        std::cout << "不允许发送: ";
        for (int i = sendBase + windowSize; i < nextSeqNum + windowSize; i++) {
            std::cout << i << " ";
        }
        std::cout << std::endl;

        std::cout << "已发送确认并交付主机: ";
        for (int i = 0; i < sendBase; i++) {
            std::cout << i << " ";
        }
        std::cout << std::endl;

        std::cout << "允许接收: ";
        for (int i = sendBase; i < sendBase + windowSize; i++) {
            std::cout << i << " ";
        }
        std::cout << std::endl;

        std::cout << "不允许接收: ";
        for (int i = sendBase + windowSize; i < nextSeqNum + windowSize; i++) {
            std::cout << i << " ";
        }
        std::cout << std::endl;

        std::cout << "通知窗口大小: " << windowSize - (nextSeqNum - sendBase) << std::endl;
        std::cout << "可用窗口大小: " << windowSize - (nextSeqNum - sendBase) << std::endl;

        std::this_thread::sleep_for(std::chrono::seconds(1));
    }
}

int main() {
    for (int i = 0; i < windowSize; i++) {
        receivedAck[i] = false;
    }

    std::thread senderThread(sender);
    std::thread receiverThread(receiver);
    std::thread monitorThread(monitor);

    std::this_thread::sleep_for(std::chrono::seconds(10));
    stop = true;

    senderThread.join();
    receiverThread.join();
    monitorThread.join();

    return 0;
}